基于nRF52832 SoC的RedBear BLE Nano v2物联网开发板初体验

Author Avatar
$H_P? Mar 04, 2018
  • Read this article on other devices

IoT大杀器nRF52832

nRF52832 SoC芯片主要参数:

  • ARM Cortex-M4,32-bit
  • 最大主频64 MHz
  • 内部闪存512kB
  • SRAM达到64kB
  • 支持Bluetooth 5和NFC
  • 支持多种开发环境

相比之下Arduino Uno的ATmega328芯片的主频才16MHz,Flash 32kB,SRAM 2kB,不带任何无线功能。对比强烈。

Nordic的官方组件评测可以看:
一款基于Cortex-M4的BLE SoC——Nordic nRF52开发套件评测_搜狐科技_搜狐网
Arduino也推出了Primo这个板子:
Arduino使用Nordic nRF52832 SoC的Arduino Primo基板-通信/网络-与非网

RedBear BLE Nano Kit v2

入手的是RedBear推出的超小型开发板。小巧全能就是王道!
这个板子虽然是某香港/深圳公司做的,中文世界的介绍几乎没有,RedBear的人看到此文不介意给本人支付广告费(@HᴗP@)。

nRF52832的特性之外,还有:

  • Arduino IDE,Mbed,JavaScript,Nordic nRF52 SDK,Python,Apache Mynewt,FreeRTOS等开发环境
  • 板载LED D13
  • UART,SPI,I2C
  • 最大11个端口,也足够用了
  • VDD除了3.3V,还支持1.8V的输出
  • 可以在1.8V-3.6V工作
  • 大小只有大概2厘米见方
  • 支持Over-The-Air,也就是不连电脑直接通过BLE写程序

还有官方Kit,多了USB读写器DAPLink

开发板介绍:
Kickstarter page
nRF5x/nRF52832 at master · redbear/nRF5x · GitHub
RedBear (注意:官网是找不到Nano2介绍页面的=͟͟͞͞(HㅍP),只有
基于nRF51832的一代Nano的介绍,两代非常不同 )

官方还有扩展板

RedBear BLE Nano Kit v2开箱

可以看到其实BLE Nano的板子只比USB插口大了一点点,大概就是正常人的拇指那么大吧。下面作对比的是ESP32。

插电前必须注意插入读写器的方向,白色的小熊logo是朝外的。

插电后就可以进行BLE测试,本来已经预先安装了心率服务:nRF5x/Getting_Started_Guide.md at master · redbear/nRF5x · GitHub

windows系统可能需要先安装mbed的驱动:https://developer.mbed.org/handbook/Windows-serial-configuration

Arduino IDE追加库

按照官方介绍操作:nRF5x/Arduino_Board_Package_Installation_Guide.md at master · redbear/nRF5x · GitHub

安装完了之后就可以看到IDE里面出现了BLE_Nano2的板子,注意不要搞混一代Nano和二代了,两者不通用。

这时候可以进行Arduino标准的LED测试,记得端口换成D13就行。

BLE Simple Chat测试

先安装官方的APP:BLEController
Arduino IDE里面打开File>Examples>BLE_Examples>SimpleChat并上传

官方APP里面找到设备并连接,
在手机里面输入文字,Serial Monitor里面就有反应。

反过来Serial Monitor里面输入文字,手机就有输出。
实现简单的文字传输功能。

并非Arduino风格的BLE语法

好了,用是可以使用,看一下具体代码的话就会发现,BLE部分的语法并不是一般arduino里面常用的那种,而是类似mbed的语法,这个说明又是一个大坑了。
另外可以用Nordic SDK,自由度更高,开发HID等高级功能逃不过,当然这个坑更大更深。

  1. /*
  2. * Copyright (c) 2016 RedBear
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
  5. * to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
  6. * and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
  7. *
  8. * The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
  9. *
  10. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  11. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  12. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
  13. * IN THE SOFTWARE.
  14. */
  15. #include <nRF5x_BLE_API.h>
  16. #define DEVICE_NAME "BLE_Peripheral" // 被搜索的时候看到的名字
  17. #define TXRX_BUF_LEN 20 // 这个是BLE每次传输缓冲的最大字节数,最大20
  18. BLE ble;
  19. Timeout timeout;
  20. static uint8_t rx_buf[TXRX_BUF_LEN]; // 这个是BLE每次传输缓冲的最大字节数,最大20
  21. static uint8_t rx_buf_num;
  22. static uint8_t rx_state=0;
  23. // 需要自己定义16进制的uuid
  24. // The uuid of service and characteristics
  25. static const uint8_t service1_uuid[] = {0x71, 0x3D, 0, 0, 0x50, 0x3E, 0x4C, 0x75, 0xBA, 0x94, 0x31, 0x48, 0xF1, 0x8D, 0x94, 0x1E};
  26. static const uint8_t service1_tx_uuid[] = {0x71, 0x3D, 0, 3, 0x50, 0x3E, 0x4C, 0x75, 0xBA, 0x94, 0x31, 0x48, 0xF1, 0x8D, 0x94, 0x1E};
  27. static const uint8_t service1_rx_uuid[] = {0x71, 0x3D, 0, 2, 0x50, 0x3E, 0x4C, 0x75, 0xBA, 0x94, 0x31, 0x48, 0xF1, 0x8D, 0x94, 0x1E};
  28. static const uint8_t uart_base_uuid_rev[] = {0x1E, 0x94, 0x8D, 0xF1, 0x48, 0x31, 0x94, 0xBA, 0x75, 0x4C, 0x3E, 0x50, 0, 0, 0x3D, 0x71};
  29. uint8_t tx_value[TXRX_BUF_LEN] = {0,};
  30. uint8_t rx_value[TXRX_BUF_LEN] = {0,};
  31. // Initialize value of chars
  32. GattCharacteristic characteristic1(service1_tx_uuid, tx_value, 1, TXRX_BUF_LEN, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE | GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_WRITE_WITHOUT_RESPONSE ); // 定义特征的读写权限等
  33. GattCharacteristic characteristic2(service1_rx_uuid, rx_value, 1, TXRX_BUF_LEN, GattCharacteristic::BLE_GATT_CHAR_PROPERTIES_NOTIFY);
  34. GattCharacteristic *uartChars[] = {&characteristic1, &characteristic2};
  35. GattService uartService(service1_uuid, uartChars, sizeof(uartChars) / sizeof(GattCharacteristic *));
  36. // BLE断开后的操作
  37. void disconnectionCallBack(const Gap::DisconnectionCallbackParams_t *params) {
  38. Serial.println("Disconnected!");
  39. Serial.println("Restarting the advertising process");
  40. ble.startAdvertising(); // 开始advertising
  41. }
  42. // central设备有write请求时候的操作
  43. void gattServerWriteCallBack(const GattWriteCallbackParams *Handler) {
  44. uint8_t buf[TXRX_BUF_LEN];
  45. uint8_t index;
  46. uint16_t bytesRead = TXRX_BUF_LEN;
  47. Serial.println("onDataWritten : ");
  48. if (Handler->handle == characteristic1.getValueAttribute().getHandle()) {
  49. // 读出特征的数据
  50. ble.readCharacteristicValue(characteristic1.getValueAttribute().getHandle(), buf, &bytesRead);
  51. Serial.print("bytesRead: ");
  52. Serial.println(bytesRead, HEX);
  53. for(index=0; index<bytesRead; index++) {
  54. Serial.write(buf[index]);
  55. }
  56. Serial.println("");
  57. }
  58. }
  59. void m_uart_rx_handle() { //update characteristic data
  60. ble.updateCharacteristicValue(characteristic2.getValueAttribute().getHandle(), rx_buf, rx_buf_num);
  61. memset(rx_buf, 0x00,20);
  62. rx_state = 0;
  63. }
  64. void uart_handle(uint32_t id, SerialIrq event) { /* Serial rx IRQ */
  65. if(event == RxIrq) {
  66. if(rx_state == 0) {
  67. rx_state = 1;
  68. timeout.attach_us(m_uart_rx_handle, 100000);
  69. rx_buf_num=0;
  70. }
  71. while(Serial.available()) {
  72. if(rx_buf_num < 20) {
  73. rx_buf[rx_buf_num] = Serial.read();
  74. rx_buf_num++;
  75. }
  76. else {
  77. Serial.read();
  78. }
  79. }
  80. }
  81. }
  82. void setup() {
  83. // put your setup code here, to run once
  84. Serial.begin(9600);
  85. Serial.attach(uart_handle);
  86. ble.init();
  87. ble.onDisconnection(disconnectionCallBack);
  88. ble.onDataWritten(gattServerWriteCallBack);
  89. // setup adv_data and srp_data
  90. ble.accumulateAdvertisingPayload(GapAdvertisingData::BREDR_NOT_SUPPORTED);
  91. ble.accumulateAdvertisingPayload(GapAdvertisingData::SHORTENED_LOCAL_NAME,
  92. (const uint8_t *)"TXRX", sizeof("TXRX") - 1);
  93. ble.accumulateAdvertisingPayload(GapAdvertisingData::COMPLETE_LIST_128BIT_SERVICE_IDS,
  94. (const uint8_t *)uart_base_uuid_rev, sizeof(uart_base_uuid_rev));
  95. // set adv_type
  96. ble.setAdvertisingType(GapAdvertisingParams::ADV_CONNECTABLE_UNDIRECTED);
  97. // add service
  98. ble.addService(uartService);
  99. // set device name
  100. ble.setDeviceName((const uint8_t *)"Simple Chat");
  101. // set tx power,valid values are -40, -20, -16, -12, -8, -4, 0, 4
  102. ble.setTxPower(4);
  103. // set adv_interval, 100ms in multiples of 0.625ms.
  104. ble.setAdvertisingInterval(160);
  105. // set adv_timeout, in seconds
  106. ble.setAdvertisingTimeout(0);
  107. // start advertising
  108. ble.startAdvertising();
  109. Serial.println("Advertising Start!");
  110. }
  111. void loop() {
  112. ble.waitForEvent();
  113. }

诸多参考

BLE Nanoを試してみました - surga Lab
RedBearLab BLE Nano の設定方法とOTA | Home Made Garbage
BLE Car01
blenanov2をarduinoideを使ってプログラミングする方法
【Arduino】BLE NanoでスマートフォンとBLE通信する - おもちゃラボ
ArduinoRedBearLab BLE Nanoを使ってみる : 工作と競馬
BLE NanoではじめてのBLE通信!クラゲのIoTテクノロジー
BLE Nano2ではじめてのBLE通信!クラゲのIoTテクノロジー
BLEnanoで必要なときだけLCDに情報を表示する方法 : 試行錯誤な日々

有事别忘了骚扰官方论坛:BLE Nano 2 (nRF52832) - Discussion Forums

վ HᴗP ի

This blog is under a CC BY-NC-SA 3.0 Unported License
Link to this article: https://hanspond.github.io/2018/03/04/基于nRF52832 SoC的RedBear BLE NANO Kit v2物联网开发板初体验/